import os
import time
import numpy as np
from sympy import primerange, nextprime


def get_last_prime_from_file(file_name, dtype):
    """Retrieve the last prime from the binary file."""
    try:
        with open(file_name, 'rb') as file:
            file.seek(-np.dtype(dtype).itemsize, os.SEEK_END)
            last_prime_bytes = file.read(np.dtype(dtype).itemsize)
            return int.from_bytes(last_prime_bytes, byteorder='little', signed=True)
    except (FileNotFoundError, OSError):
        return 1  # File does not exist or other OS error, start from the first prime's predecessor


def append_primes_to_binary(file_name: str, count: int, data_size: int = 4):
    """Append primes to a binary file."""
    if data_size not in (4, 8):
        raise ValueError("Data size must be 4 (int32) or 8 (int64).")

    dtype = np.int32 if data_size == 4 else np.int64
    start_prime = get_last_prime_from_file(file_name, dtype)
    start_prime = nextprime(start_prime)

    primes = list(primerange(start_prime, start_prime + count))
    primes_array = np.array(primes, dtype=dtype)
    with open(file_name, 'ab') as file:
        file.write(primes_array.tobytes())


def print_primes_from_file(file_name, count, data_size):
    """Print primes from a binary file."""
    if data_size not in (4, 8):
        raise ValueError("Data size must be 4 (int32) or 8 (int64).")

    dtype = np.int32 if data_size == 4 else np.int64

    try:
        if count == -1:
            primes = np.fromfile(file_name, dtype=dtype)
        else:
            primes = np.fromfile(file_name, dtype=dtype, count=count)
        for prime in primes:
            print(prime)
    except FileNotFoundError:
        print(f"File {file_name} not found.")
    except Exception as e:
        print(f"An error occurred while reading the file: {e}")


# 示例使用
n = int(1e8)
star = time.time()
append_primes_to_binary('primes1.bin', n, 8)
print(f"耗时：{time.time() - star}s")

# 使用 np.int64 作为 dtype 的参数
print(f"最后得素数：{get_last_prime_from_file('primes1.bin', np.int64)}")